using Joy.Erp.BasicArchives.Core.Filters;
using Joy.Erp.BasicArchives.HttpApi.SimplyClient.Core;
using Joy.Erp.BasicArchives.Receipt;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Joy.Erp.BasicArchives.HttpApi.SimplyClient.Receipt
{
    public class ReceivementClientProxy
    {
        public readonly TokenClientProxy TokenClientProxy;

        public ReceivementClientProxy(TokenClientProxy tokenClientProxy)
        {
            TokenClientProxy = tokenClientProxy;
        }

        public async Task<ReceivementDto> GetAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/{id}");

            return await ApiHandler.HttpGetAsync<ReceivementDto>(token, url, logfunc);
        }

        public ReceivementDto Get(Guid id, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await GetAsync(id, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementLineDto> GetChildAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/child/{id}");

            return await ApiHandler.HttpGetAsync<ReceivementLineDto>(token, url, logfunc);
        }

        public ReceivementLineDto GetChild(Guid id, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await GetChildAsync(id, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> FindAsync(string filter, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/find?filter={filter}");

            return await ApiHandler.HttpGetAsync<ReceivementDto>(token, url, logfunc);
        }

        public ReceivementDto Find(string filter, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await FindAsync(filter, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> FindBySourceKeyAsync(string sourceKey, string sourceType, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/find-by-source-key?sourceKey={sourceKey}&sourceType={sourceType}");

            return await ApiHandler.HttpGetAsync<ReceivementDto>(token, url, logfunc);
        }

        public ReceivementDto FindBySourceKey(string sourceKey, string sourceType, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await FindBySourceKeyAsync(sourceKey, sourceType, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<PagedResultDto<ReceivementDto>> GetListAsync(FilterRequestDto input, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement?filter={input.Filter}&sorting={input.Sorting}&skipCount={input.SkipCount}&maxResultCount={input.MaxResultCount}");

            return await ApiHandler.HttpGetAsync<PagedResultDto<ReceivementDto>>(token, url, logfunc);
        }

        public PagedResultDto<ReceivementDto> GetList(FilterRequestDto input, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await GetListAsync(input, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<PagedResultDto<ReceivementDto>> QueryAsync(FilterGroupRequestDto input, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/query");

            return await ApiHandler.HttpPostAsync<PagedResultDto<ReceivementDto>>(token, url, input, logfunc);
        }

        public PagedResultDto<ReceivementDto> Query(FilterGroupRequestDto input, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await QueryAsync(input, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<PagedResultDto<ReceivementLineDto>> QueryChildrenAsync(FilterGroupRequestDto input, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/query-children");

            return await ApiHandler.HttpPostAsync<PagedResultDto<ReceivementLineDto>>(token, url, input, logfunc);
        }

        public PagedResultDto<ReceivementLineDto> QueryChildren(FilterGroupRequestDto input, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await QueryChildrenAsync(input, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> CreateAsync(ReceivementCreateDto input, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement");

            return await ApiHandler.HttpPostAsync<ReceivementDto>(token, url, input, logfunc);
        }

        public ReceivementDto Create(ReceivementCreateDto input, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await CreateAsync(input, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> UpdateAsync(Guid id, ReceivementUpdateDto input, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/{id}");

            return await ApiHandler.HttpPutAsync<ReceivementDto>(token, url, input, logfunc);
        }

        public ReceivementDto Update(Guid id, ReceivementUpdateDto input, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await UpdateAsync(id, input, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> SubmitAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/submit");

            var requestData = new { id };
            return await ApiHandler.HttpPostAsync<ReceivementDto>(token, url, requestData, logfunc);
        }

        public ReceivementDto Submit(Guid id, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await SubmitAsync(id, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> ApproveAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/approve");

            var requestData = new { id };
            return await ApiHandler.HttpPostAsync<ReceivementDto>(token, url, requestData, logfunc);
        }

        public ReceivementDto Approve(Guid id, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await ApproveAsync(id, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<ReceivementDto> UnApproveAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/unapprove");

            var requestData = new { id };
            return await ApiHandler.HttpPostAsync<ReceivementDto>(token, url, requestData, logfunc);
        }

        public ReceivementDto UnApprove(Guid id, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await UnApproveAsync(id, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task DeleteAsync(Guid id, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/{id}");

            await ApiHandler.HttpDeleteAsync(token, url, logfunc);
        }

        public void Delete(Guid id, Action<string> logfunc = null)
        {
            try
            {
                Task.Run(async () => await DeleteAsync(id, logfunc));
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<List<ReceivementDto>> BatchCreateAsync(List<ReceivementCreateDto> inputs, bool useBulk = false, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/batch-create?useBulk={useBulk.ToString().ToLower()}");

            return await ApiHandler.HttpPostAsync<List<ReceivementDto>>(token, url, inputs, logfunc);
        }

        public List<ReceivementDto> BatchCreate(List<ReceivementCreateDto> inputs, bool useBulk = false, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await BatchCreateAsync(inputs, useBulk, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task<List<ReceivementDto>> BatchUpdateAsync(List<ReceivementBatchUpdateDto> inputs, bool useBulk = false, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/batch-update?useBulk={useBulk.ToString().ToLower()}");

            return await ApiHandler.HttpPutAsync<List<ReceivementDto>>(token, url, inputs, logfunc);
        }

        public List<ReceivementDto> BatchUpdate(List<ReceivementBatchUpdateDto> inputs, bool useBulk = false, Action<string> logfunc = null)
        {
            try
            {
                return Task.Run(async () => await BatchUpdateAsync(inputs, useBulk, logfunc)).Result;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }

        public async Task BatchDeleteAsync(List<Guid> ids, bool useBulk = false, Action<string> logfunc = null)
        {
            var token = await TokenClientProxy.GetToken(logfunc);
            var url = TokenClientProxy.Config.ApiUrl.AppendUrl($"api/basic-archives/receivement/batch-delete?useBulk={useBulk.ToString().ToLower()}");

            await ApiHandler.HttpPostAsync<object>(token, url, ids, logfunc);
        }

        public void BatchDelete(List<Guid> ids, bool useBulk = false, Action<string> logfunc = null)
        {
            try
            {
                Task.Run(async () => await BatchDeleteAsync(ids, useBulk, logfunc));
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }
    }
} 
